package com.ys.gulimall.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.ys.common.utils.R;
import com.ys.gulimall.feign.ProductFeignService;
import com.ys.gulimall.interceptor.CartInterceptor;
import com.ys.gulimall.service.CartService;
import com.ys.gulimall.vo.CartItemVo;
import com.ys.gulimall.vo.CartVo;
import com.ys.gulimall.vo.SkuInfoVo;
import com.ys.gulimall.vo.UserInfoTo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * @Description:
 * @author： yeswater
 * @create： 2024/5/17
 */

@Slf4j
@Service
public class CartServiceImpl implements CartService {
	
	private final String CART_PREFIX = "gulimall:cart:";
	
	@Resource
	private StringRedisTemplate stringRedisTemplate;
	
	@Resource
	private ProductFeignService productFeignService;
	
	@Resource
	private ThreadPoolExecutor executor;
	
	@Override
	public CartItemVo addToCart(Long skuId, Integer num) throws ExecutionException, InterruptedException {
		BoundHashOperations<String, Object, Object> cartOps = getCartOps();
		
		String res = (String) cartOps.get(skuId.toString());
		// 1、添加新商品到购物车（购物车无此商品） 
		if (StringUtils.isEmpty(res)) {
			CartItemVo cartItem = new CartItemVo();
			
			/**
			 * 异步查询
			 */
			CompletableFuture<Void> getSkuInfo = CompletableFuture.runAsync(() -> {
				//1.1、远程查询要添加的商品信息
				R skuInfo = productFeignService.info(skuId);
				SkuInfoVo data = skuInfo.getData("skuInfo", new TypeReference<SkuInfoVo>() {
				});
				
				cartItem.setCheck(true);
				cartItem.setCount(1);
				cartItem.setImage(data.getSkuDefaultImg());
				cartItem.setTitle(data.getSkuTitle());
				cartItem.setSkuId(skuId);
				cartItem.setPrice(data.getPrice());
			}, executor);
			CompletableFuture<Void> getSkuSaleAttrValues = CompletableFuture.runAsync(() -> {
				//1.2、远程查询sku的组合信息
				List<String> values = productFeignService.getSkuSaleAttrValues(skuId);
				cartItem.setSkuAttrValues(values);
			}, executor);
			// 阻塞等待各个任务执行完成
			CompletableFuture.allOf(getSkuInfo, getSkuSaleAttrValues).get();
			String jsonString = JSON.toJSONString(cartItem);
			cartOps.put(skuId.toString(), jsonString);
			return cartItem;
		} else {
			//2、购物车有此商品，将数据取出修改数量即可
			CartItemVo cartItem = JSON.parseObject(res, CartItemVo.class);
			cartItem.setCount(cartItem.getCount() + num);
			cartOps.put(skuId.toString(), JSON.toJSONString(cartItem));
			return cartItem;
		}
	}
	
	/**
	 * 获取购物车中的商品
	 */
	@Override
	public CartItemVo getCartItem(Long skuId) {
		BoundHashOperations<String, Object, Object> cartOps = getCartOps();
		String item = (String) cartOps.get(skuId.toString());
		CartItemVo cartItem = JSON.parseObject(item, CartItemVo.class);
		return null;
	}
	
	@Override
	public CartVo getCart() throws ExecutionException, InterruptedException {
		CartVo cart = new CartVo();
		//1、登录
		UserInfoTo userInfoTo = CartInterceptor.threadLocal.get();
		if (userInfoTo.getUserId() != null){
			String cartKey = CART_PREFIX + userInfoTo.getUserId();
			
			//1.1、如果临时购物车的数据还没有合并【合并购物车】
			String tempCartKey = CART_PREFIX + userInfoTo.getUserKey();
			List<CartItemVo> tempsCartItems = getCartItems(tempCartKey);
			if (tempsCartItems != null){
				//临时购物车有数据，需要合并
				for (CartItemVo item : tempsCartItems) {
					addToCart(item.getSkuId(),item.getCount());
				}
				//清除临时购物车的数据
				clearCart(tempCartKey);
			}
			
			//1.2、获取登录后的购物车数据【包含合并过来的临时购物车的数据，和登录后的购物车数据 】
			List<CartItemVo> cartItems = getCartItems(cartKey);
			cart.setItems(cartItems);
		}else {
			//2、没登录
			String cartKey = CART_PREFIX + userInfoTo.getUserKey();
			//获取临时购物车的所有购物项
			List<CartItemVo> cartItems = getCartItems(cartKey);
			cart.setItems(cartItems);
		}
		return cart;
	}
	
	@Override
	public void clearCart(String cartKey) {
		stringRedisTemplate.delete(cartKey);
	}
	
	/**
	 * 获取购物车里面的数据
	 * @param cartKey
	 * @return
	 */
	private List<CartItemVo> getCartItems(String cartKey) {
		//获取购物车里面的所有商品
		BoundHashOperations<String, Object, Object> operations = stringRedisTemplate.boundHashOps(cartKey);
		List<Object> values = operations.values();
		if (values != null && values.size() > 0) {
			List<CartItemVo> cartItemVoStream = values.stream().map((obj) -> {
				String str = (String) obj;
				CartItemVo cartItem = JSON.parseObject(str, CartItemVo.class);
				return cartItem;
			}).collect(Collectors.toList());
			return cartItemVoStream;
		}
		return null;
		
	}
	
	@Override
	public void checkItem(Long skuId, Integer check) {
		
		//查询购物车里面的商品
		CartItemVo cartItem = getCartItem(skuId);
		//修改商品状态
		cartItem.setCheck(check == 1);
		
		//序列化存入redis中
		String redisValue = JSON.toJSONString(cartItem);
		
		BoundHashOperations<String, Object, Object> cartOps = getCartOps();
		cartOps.put(skuId.toString(),redisValue);
		
	}
	
	/**
	 * 修改购物项数量
	 * @param skuId
	 * @param num
	 */
	@Override
	public void changeItemCount(Long skuId, Integer num) {
		
		//查询购物车里面的商品
		CartItemVo cartItem = getCartItem(skuId);
		cartItem.setCount(num);
		
		BoundHashOperations<String, Object, Object> cartOps = getCartOps();
		//序列化存入redis中
		String redisValue = JSON.toJSONString(cartItem);
		cartOps.put(skuId.toString(),redisValue);
	}
	
	private BoundHashOperations<String, Object, Object> getCartOps() {
		UserInfoTo userInfoTo = CartInterceptor.threadLocal.get();
		String cartKey = "";
		if (userInfoTo.getUserId() != null) {
			cartKey = CART_PREFIX + userInfoTo.getUserId();
		} else {
			cartKey = CART_PREFIX + userInfoTo.getUserKey();
		}
		BoundHashOperations<String, Object, Object> boundHashOperations = stringRedisTemplate.boundHashOps(cartKey);
		return boundHashOperations;
	}
	
	/**
	 * 删除购物项
	 * @param skuId
	 */
	@Override
	public void deleteIdCartInfo(Integer skuId) {
		
		BoundHashOperations<String, Object, Object> cartOps = getCartOps();
		cartOps.delete(skuId.toString());
	}
	
	@Override
	public List<CartItemVo> getUserCartItems() {
		UserInfoTo userInfoTo = CartInterceptor.threadLocal.get();
		if (userInfoTo.getUserId() == null){
			return null;
		}else {
			String cartKey = CART_PREFIX + userInfoTo.getUserId();
			List<CartItemVo> cartItems = getCartItems(cartKey);
			//获取所有被选中的购物项
			List<CartItemVo> collect = cartItems.stream().filter(item -> item.getCheck())
					                         .map(item->{
						                         R price = productFeignService.getPrice(item.getSkuId());
						                         //更新为最新价格
						                         String data = (String) price.get("data");
						                         item.setPrice(new BigDecimal(data));
						                         return item;})
					                         .collect(Collectors.toList());
			return collect;
		}
		
	}
	
}
